package com.ruoyi.biz.system.service.impl;

import com.ruoyi.biz.system.domain.SysUploadFileInfo;
import com.ruoyi.biz.system.mapper.SysUploadFileInfoMapper;
import com.ruoyi.biz.system.service.ISysUploadFileInfoService;
import com.ruoyi.biz.util.FilePathUtil;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.Seq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Optional;

import static com.ruoyi.common.utils.file.FileUploadUtils.getAbsoluteFile;
import static com.ruoyi.common.utils.file.FileUploadUtils.getPathFileName;

@Service
public class SysUploadFileInfoService implements ISysUploadFileInfoService {

    private final SysUploadFileInfoMapper sysUploadFileInfoMapper;

    public SysUploadFileInfoService(SysUploadFileInfoMapper sysUploadFileInfoMapper) {
        this.sysUploadFileInfoMapper = sysUploadFileInfoMapper;
    }

    @Override
    public SysUploadFileInfo save(byte[] fileData, String fileName, String path, Long userId) throws IOException {
        // 将文件保存到服务器文件系统
        String newRelativeFilePath = upload(path, fileData, fileName);
        // 将信息保存到数据库
        SysUploadFileInfo sysUploadFileInfo = new SysUploadFileInfo();
        sysUploadFileInfo.setPath(newRelativeFilePath);
        // 文件原始文件
        sysUploadFileInfo.setName(fileName);
        sysUploadFileInfo.setCreateBy(userId);
        sysUploadFileInfo.setCreateTime(new Date());
        sysUploadFileInfoMapper.insertSysUploadFileInfo(sysUploadFileInfo);
        return sysUploadFileInfo;
    }

    @Override
    public Optional<File> getFile(Long fileId) {
        Optional<SysUploadFileInfo> sysUploadFileInfoOptional = sysUploadFileInfoMapper.selectSysUploadFileInfoById(fileId);
        if(sysUploadFileInfoOptional.isPresent()) {
            SysUploadFileInfo sysUploadFileInfo = sysUploadFileInfoOptional.get();
            Path path = FilePathUtil.getRealPath(sysUploadFileInfo.getPath());
            return Optional.of(path.toFile());
        }

        return Optional.empty();
    }

    private String upload(String baseDir, byte[] fileData, String originalFileName)
            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException {
        String fileName = extractFilename(originalFileName);

        String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
        Files.write(Paths.get(absPath), fileData);
        return getPathFileName(baseDir, fileName);
    }

    /**
     * 重命名文件
     */
    private String extractFilename(String originalFileName) {
        return StringUtils.format(
                "{}/{}_{}.{}",
                DateUtils.datePath(),
                FilenameUtils.getBaseName(originalFileName),
                Seq.getId(Seq.uploadSeqType), getExtension(originalFileName));
    }

    /**
     * 获取文件名的后缀
     *
     * @return 后缀名
     */
    private String getExtension(String originalFileName) {
        return FilenameUtils.getExtension(originalFileName);
    }
}
